import clsx from "clsx";
import Link from "next/link";
import { FormEvent, useContext, useMemo } from "react";
import { useRouter } from "next/router";
import { GetServerSideProps } from "next";

import { get } from "libs/http";
import useGet from "libs/hooks/useGet";
import { Context } from "libs/context";
import NovelItem from "components/NovelItem";

import styles from "styles/genre.module.scss";
import useStore from "libs/hooks/useStore";
import { SeoHead, SeoHeadConfig } from "components/SeoHead";
import Pagination from "components/Pagination";
import PaginationItem from "components/Pagination/PaginationItem";
import SearchForm from "components/common/SearchForm";
import EmptyResult from "components/EmptyResult";

interface Query {
  genre?: string;
  page?: string;
  q?: string;
}

function getKey(query: Query = {}) {
  const queryString = `?page=${
    isNaN(Number(query.page)) ? "1" : query.page
  }&size=20`;

  return query.q
    ? `/api/search${queryString}${
        query.genre ? `&genre=${query.genre}` : ""
      }&name=${query.q}`
    : query.genre
    ? `/api/genre/${query.genre}${queryString}`
    : `/api/all${queryString}`;
}

const Genre = () => {
  const { query, asPath } = useRouter();
  const { genre, siteConfig } = useStore();
  const { data } = useGet<NovelList>(getKey(query));
  const currentName = useMemo(() => {
    const item = genre.find((item) => item.uri === query.genre);
    return item ? item.name : "All";
  }, [query.genre, genre]);
  const pashName = useMemo(() => {
    return asPath.split("?")[0];
  }, [asPath]);

  const seoConfig: SeoHeadConfig = useMemo(() => {
    // const genreName =
    return {
      title: `${currentName} Novels - ${siteConfig.siteName}`,
      description: `Explore ${currentName} Web Novels on NovelDit. Online Reading ${currentName} Web Novels for Free!`,
      keywords: `${[
        `${currentName} stories`,
        `${currentName} novels`,
        `read ${currentName} novels`,
        siteConfig.keywords,
        siteConfig.siteName,
      ].join(", ")}`,
      url: `https://${siteConfig.host}/novels${
        query.genre ? `/${query.genre}` : ""
      }`,
      canonical: `https://${siteConfig.host}/novels${
        query.genre ? `/${query.genre}` : ""
      }`,
      ...(data?.data.pageIndex && data.data.pageIndex > 1
        ? {
            pre: `https://${siteConfig.host}/novels${
              query.genre ? `/${query.genre}` : ""
            }${query.q ? `?q=${query.q}` : ""}${
              data.data.pageIndex - 1 === 1
                ? ""
                : `${query.q ? `&` : "?"}page=${data.data.pageIndex - 1}`
            }`,
          }
        : {}),
      ...(data?.data.pageSize &&
      data?.data.pageIndex &&
      data.data.pageSize > data.data.pageIndex
        ? {
            next: `https://${siteConfig.host}/novels${
              query.genre ? `/${query.genre}` : ""
            }${query.q ? `?q=${query.q}` : ""}${`${query.q ? `&` : "?"}page=${
              data.data.pageIndex + 1
            }`}`,
          }
        : {}),
      jsonLd: JSON.stringify([
        {
          "@context": "https://schema.org",
          "@type": "BreadcrumbList",
          itemListElement: [
            {
              "@type": "ListItem",
              position: 1,
              name: "Home",
              item: `https://${siteConfig.host}`,
            },
            {
              "@type": "ListItem",
              position: 2,
              name: "All Novels",
              item: `https://${siteConfig.host}/novels`,
            },
            ...(query.genre
              ? [
                  {
                    "@type": "ListItem",
                    position: 3,
                    name: `${currentName} Novels`,
                    item: `https://${siteConfig.host}/novels/${query.genre}`,
                  },
                ]
              : []),
          ],
        },
        {
          "@context": "https://schema.org",
          "@type": "ItemList",
          itemListElement: (data?.data.rows || []).map((item, idx) => ({
            "@type": "ListItem",
            position: idx + 1,
            url: `https://${siteConfig.host}/novel/${item.uri}`,
            name: item.name,
            image:
              "http://img.webnovel.com/bookcover/16709365405930105/600/600.jpg",
            author: { "@type": "Person", name: item.author },
            publisher: { "@type": "Organization", name: siteConfig.siteName },
          })),
        },
        ...siteConfig.jsonLd,
      ]),
    };
  }, [
    currentName,
    data?.data.rows,
    query.genre,
    siteConfig.host,
    siteConfig.jsonLd,
    siteConfig.keywords,
    siteConfig.siteName,
  ]);

  return (
    <main className="container">
      <SeoHead seoConfig={seoConfig} />
      <h2 className="novel-title">Genres</h2>
      <div className={styles.genres}>
        <Link
          href="/novels"
          title="All novels"
          className={clsx(styles.genre, {
            [styles.current]: !query.genre,
          })}
        >
          All
        </Link>
        {genre.map((item) => (
          <Link
            href={`/novels/${item.uri}`}
            key={item.uri}
            title={item.name}
            className={clsx(styles.genre, {
              [styles.current]: query.genre === item.uri,
            })}
          >
            {item.name}
          </Link>
        ))}
      </div>
      <h3 className="novel-title">Search</h3>
      <SearchForm />
      <h2 className="novel-title">{`${currentName} Novels`}</h2>
      {data?.data.rows && data.data.rows.length > 0 ? (
        <ul className="novel-list">
          {(data?.data.rows || []).map((item) => (
            <NovelItem
              key={item.uri}
              slug={item.uri}
              img={item.img}
              name={item.name}
            />
          ))}
        </ul>
      ) : (
        <EmptyResult
          icon="autoStories"
          title={`Couldn't find books${
            query.q ? ` matching "${query.q}"` : ""
          }.`}
        />
      )}
      {data?.data.total_pages && data.data.total_pages > 1 ? (
        <Pagination
          className="mt-5"
          count={data?.data.total_pages}
          page={data?.data.pageIndex}
          renderItem={(item) => (
            <PaginationItem
              component={Link}
              href={`${pashName}${query.q ? `?q=${query.q}` : ""}${
                item.page === 1 ? "" : `${query.q ? `&` : "?"}page=${item.page}`
              }`}
              {...item}
            />
          )}
        />
      ) : null}
    </main>
  );
};

export const getServerSideProps: GetServerSideProps<{
  fallback: Docs;
}> = async ({ query }) => {
  const key = getKey(query);
  const data = await get(key);

  return {
    props: {
      fallback: {
        [key]: data,
      },
    },
  };
};

export default Genre;
